#include <iostream>
#include <cmath>
#include <vector>
#include <random>
#include <fstream>

using namespace std;

const double PI = 3.14159265358979323846;
const double SAMPLE_RATE = 1000.0; // 采样率
const double CARRIER_FREQ = 50.0;  // 载波频率
const double MESSAGE_FREQ = 5.0;   // 调制信号频率
const double AMPLITUDE = 1.0;      // 振幅

// 生成载波信号（正弦波）
int generate_cover_signal(double *cover, const int size) {
    if (size <= 0) return -1;
    
    for (int i = 0; i < size; i++) {
        double t = i / SAMPLE_RATE;
        cover[i] = AMPLITUDE * sin(2 * PI * CARRIER_FREQ * t);
    }
    
    return 0;
}

// 生成数字调制信号（0和1序列）
int simulate_digital_modulation_signal(unsigned char *message, const int size) {
    if (size <= 0) return -1;
    
    // 使用随机数生成器生成0和1
    random_device rd;
    mt19937 gen(rd());
    uniform_int_distribution<> dis(0, 1);
    
    for (int i = 0; i < size; i++) {
        message[i] = dis(gen);
    }
    
    return 0;
}

// 生成模拟调制信号（正弦波）
int simulate_analog_modulation_signal(double *message, const int size) {
    if (size <= 0) return -1;
    
    for (int i = 0; i < size; i++) {
        double t = i / SAMPLE_RATE;
        message[i] = 0.5 * sin(2 * PI * MESSAGE_FREQ * t);
    }
    
    return 0;
}

// 数字调频
int modulate_digital_frequency(double *modulated, const int cover_len, const unsigned char *message, const int msg_len) {
    if (cover_len <= 0 || msg_len <= 0) return -1;
    
    // 计算每个消息位持续的样本数
    int samples_per_bit = cover_len / msg_len;
    if (samples_per_bit <= 0) return -1;
    
    // 频率偏移参数
    double freq_shift = 20.0; // Hz
    
    for (int i = 0; i < msg_len; i++) {
        double freq = CARRIER_FREQ + (message[i] ? freq_shift : -freq_shift);
        
        for (int j = 0; j < samples_per_bit && i * samples_per_bit + j < cover_len; j++) {
            int idx = i * samples_per_bit + j;
            double t = idx / SAMPLE_RATE;
            modulated[idx] = AMPLITUDE * sin(2 * PI * freq * t);
        }
    }
    
    return 0;
}

// 模拟调频
int modulate_analog_frequency(double *modulated, const int cover_len, const double *message, const int msg_len) {
    if (cover_len <= 0 || msg_len <= 0) return -1;
    
    // 计算每个消息样本对应的载波样本数
    double ratio = (double)cover_len / msg_len;
    
    // 频率偏移参数
    double freq_deviation = 20.0; // Hz
    
    for (int i = 0; i < cover_len; i++) {
        int msg_idx = (int)(i / ratio);
        if (msg_idx >= msg_len) msg_idx = msg_len - 1;
        
        double t = i / SAMPLE_RATE;
        double instantaneous_freq = CARRIER_FREQ + freq_deviation * message[msg_idx];
        modulated[i] = AMPLITUDE * sin(2 * PI * instantaneous_freq * t);
    }
    
    return 0;
}

// 数字调幅
int modulate_digital_amplitude(double *modulated, const int cover_len, const unsigned char *message, const int msg_len) {
    if (cover_len <= 0 || msg_len <= 0) return -1;
    
    // 计算每个消息位持续的样本数
    int samples_per_bit = cover_len / msg_len;
    if (samples_per_bit <= 0) return -1;
    
    // 生成载波信号
    double *carrier = new double[cover_len];
    generate_cover_signal(carrier, cover_len);
    
    for (int i = 0; i < msg_len; i++) {
        double amplitude = message[i] ? AMPLITUDE : 0.2 * AMPLITUDE;
        
        for (int j = 0; j < samples_per_bit && i * samples_per_bit + j < cover_len; j++) {
            int idx = i * samples_per_bit + j;
            modulated[idx] = amplitude * carrier[idx];
        }
    }
    
    delete[] carrier;
    return 0;
}

// 模拟调幅
int modulate_analog_amplitude(double *modulated, const int cover_len, const double *message, const int msg_len) {
    if (cover_len <= 0 || msg_len <= 0) return -1;
    
    // 计算每个消息样本对应的载波样本数
    double ratio = (double)cover_len / msg_len;
    
    // 生成载波信号
    double *carrier = new double[cover_len];
    generate_cover_signal(carrier, cover_len);
    
    for (int i = 0; i < cover_len; i++) {
        int msg_idx = (int)(i / ratio);
        if (msg_idx >= msg_len) msg_idx = msg_len - 1;
        
        // 调制信号范围为[-0.5, 0.5]，调制后振幅范围为[0.5, 1.5]
        double amplitude = 1.0 + message[msg_idx];
        modulated[i] = amplitude * carrier[i];
    }
    
    delete[] carrier;
    return 0;
}

// 数字调相
int modulate_digital_phase(double *modulated, const int cover_len, const unsigned char *message, const int msg_len) {
    if (cover_len <= 0 || msg_len <= 0) return -1;
    
    // 计算每个消息位持续的样本数
    int samples_per_bit = cover_len / msg_len;
    if (samples_per_bit <= 0) return -1;
    
    // 相位偏移参数
    double phase_shift = PI; // 180度相位偏移
    
    for (int i = 0; i < msg_len; i++) {
        double phase = message[i] ? phase_shift : 0;
        
        for (int j = 0; j < samples_per_bit && i * samples_per_bit + j < cover_len; j++) {
            int idx = i * samples_per_bit + j;
            double t = idx / SAMPLE_RATE;
            modulated[idx] = AMPLITUDE * sin(2 * PI * CARRIER_FREQ * t + phase);
        }
    }
    
    return 0;
}

// 模拟调相
int modulate_analog_phase(double *modulated, const int cover_len, const double *message, const int msg_len) {
    if (cover_len <= 0 || msg_len <= 0) return -1;
    
    // 计算每个消息样本对应的载波样本数
    double ratio = (double)cover_len / msg_len;
    
    // 相位偏移参数
    double phase_deviation = PI / 2; // 最大相位偏移为90度
    
    for (int i = 0; i < cover_len; i++) {
        int msg_idx = (int)(i / ratio);
        if (msg_idx >= msg_len) msg_idx = msg_len - 1;
        
        double t = i / SAMPLE_RATE;
        double phase = phase_deviation * message[msg_idx];
        modulated[i] = AMPLITUDE * sin(2 * PI * CARRIER_FREQ * t + phase);
    }
    
    return 0;
}

// 将信号保存到CSV文件
bool save_to_csv(const string& filename, double *signal, int size, double *time = nullptr) {
    ofstream file(filename);
    if (!file.is_open()) {
        ofstream log("modulation_log.txt", ios::app);
        log << "无法打开文件 " << filename << " 进行写入" << endl;
        return false;
    }
    
    file << "Time,Signal" << endl;
    
    for (int i = 0; i < size; i++) {
        double t = time ? time[i] : i / SAMPLE_RATE;
        file << t << "," << signal[i] << endl;
    }
    
    file.close();
    
    ofstream log("modulation_log.txt", ios::app);
    log << "成功保存信号到文件: " << filename << endl;
    return true;
}

// 保存数字信号到文件
bool save_digital_signal(const string& filename, const unsigned char *signal, int size) {
    ofstream file(filename);
    if (!file.is_open()) {
        ofstream log("modulation_log.txt", ios::app);
        log << "无法打开文件 " << filename << " 进行写入" << endl;
        return false;
    }
    
    file << "Index,Value" << endl;
    
    for (int i = 0; i < size; i++) {
        file << i << "," << (int)signal[i] << endl;
    }
    
    file.close();
    
    ofstream log("modulation_log.txt", ios::app);
    log << "成功保存数字信号到文件: " << filename << endl;
    return true;
}

// 测试函数
void test_modulation() {
    const int COVER_SIZE = 1000;
    const int MSG_SIZE = 20;
    
    // 清空日志文件
    ofstream log("modulation_log.txt");
    log << "=== 信号调制模拟程序 ===" << endl;
    log.close();
    
    // 分配内存
    double *cover = new double[COVER_SIZE];
    unsigned char *digital_msg = new unsigned char[MSG_SIZE];
    double *analog_msg = new double[MSG_SIZE];
    double *modulated = new double[COVER_SIZE];
    
    // 生成载波信号
    log.open("modulation_log.txt", ios::app);
    log << "正在生成载波信号..." << endl;
    log.close();
    
    generate_cover_signal(cover, COVER_SIZE);
    save_to_csv("carrier.csv", cover, COVER_SIZE);
    
    // 生成数字调制信号
    log.open("modulation_log.txt", ios::app);
    log << "正在生成数字调制信号..." << endl;
    log.close();
    
    simulate_digital_modulation_signal(digital_msg, MSG_SIZE);
    save_digital_signal("digital_message.csv", digital_msg, MSG_SIZE);
    
    log.open("modulation_log.txt", ios::app);
    log << "数字调制信号: ";
    for (int i = 0; i < MSG_SIZE; i++) {
        log << (int)digital_msg[i] << " ";
    }
    log << endl;
    log.close();
    
    // 生成模拟调制信号
    log.open("modulation_log.txt", ios::app);
    log << "正在生成模拟调制信号..." << endl;
    log.close();
    
    simulate_analog_modulation_signal(analog_msg, MSG_SIZE);
    
    // 保存模拟调制信号
    double *analog_time = new double[MSG_SIZE];
    for (int i = 0; i < MSG_SIZE; i++) {
        analog_time[i] = i * (COVER_SIZE / MSG_SIZE) / SAMPLE_RATE;
    }
    save_to_csv("analog_message.csv", analog_msg, MSG_SIZE, analog_time);
    delete[] analog_time;
    
    // 数字调频
    log.open("modulation_log.txt", ios::app);
    log << "正在进行数字调频..." << endl;
    log.close();
    
    modulate_digital_frequency(modulated, COVER_SIZE, digital_msg, MSG_SIZE);
    save_to_csv("digital_fm.csv", modulated, COVER_SIZE);
    
    // 模拟调频
    log.open("modulation_log.txt", ios::app);
    log << "正在进行模拟调频..." << endl;
    log.close();
    
    modulate_analog_frequency(modulated, COVER_SIZE, analog_msg, MSG_SIZE);
    save_to_csv("analog_fm.csv", modulated, COVER_SIZE);
    
    // 数字调幅
    log.open("modulation_log.txt", ios::app);
    log << "正在进行数字调幅..." << endl;
    log.close();
    
    modulate_digital_amplitude(modulated, COVER_SIZE, digital_msg, MSG_SIZE);
    save_to_csv("digital_am.csv", modulated, COVER_SIZE);
    
    // 模拟调幅
    log.open("modulation_log.txt", ios::app);
    log << "正在进行模拟调幅..." << endl;
    log.close();
    
    modulate_analog_amplitude(modulated, COVER_SIZE, analog_msg, MSG_SIZE);
    save_to_csv("analog_am.csv", modulated, COVER_SIZE);
    
    // 数字调相
    log.open("modulation_log.txt", ios::app);
    log << "正在进行数字调相..." << endl;
    log.close();
    
    modulate_digital_phase(modulated, COVER_SIZE, digital_msg, MSG_SIZE);
    save_to_csv("digital_pm.csv", modulated, COVER_SIZE);
    
    // 模拟调相
    log.open("modulation_log.txt", ios::app);
    log << "正在进行模拟调相..." << endl;
    log.close();
    
    modulate_analog_phase(modulated, COVER_SIZE, analog_msg, MSG_SIZE);
    save_to_csv("analog_pm.csv", modulated, COVER_SIZE);
    
    // 释放内存
    delete[] cover;
    delete[] digital_msg;
    delete[] analog_msg;
    delete[] modulated;
    
    log.open("modulation_log.txt", ios::app);
    log << "所有调制信号已保存为CSV文件，可以使用Excel或其他工具绘制图表查看" << endl;
    log << "=== 程序执行完毕 ===" << endl;
    log.close();
    
    cout << "程序执行完毕，请查看 modulation_log.txt 文件获取详细信息" << endl;
}

int main() {
    test_modulation();
    return 0;
} 